﻿using Avalonia;
using Avalonia.Controls;
using LightCAD.Core;
using LightCAD.Core.Elements;
using LightCAD.Core.Filters;
using LightCAD.Runtime;
using SkiaSharp;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Runtime.ConstrainedExecution;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using static LightCAD.Core.Elements.LcPolyLine;
using static LightCAD.Core.Elements.LcRoLine;
using static OpenTK.Graphics.OpenGL.GL;

namespace LightCAD.Drawing
{
    public class RolLineAction : ElementAction
    {
        public static string CommandName;
        public static LcCreateMethod[] CreateMethods;
        private List<Vector2d> points;
        /// <summary>
        /// 当前绘制图形状态
        /// </summary>
        private PlineSegmentType polyLineType { get; set; }
        /// <summary>
        /// 多段线第一个点
        /// </summary>
        private Vector2d? startPoint { get; set; }

        /// <summary>
        /// 多段线的第二个点
        /// </summary>
        private Vector2d? secondPoint { get; set; }

        /// <summary>
        /// 多段线的第三个点
        /// </summary>
        private Vector2d? endPoint { get; set; }
        /// <summary>
        /// 零时集合
        /// </summary>
        private List<RolineSegment> Segments { get; set; }
        static RolLineAction()
        {

            CreateMethods = new LcCreateMethod[3];
            CreateMethods[0] = new LcCreateMethod()
            {
                Name = "CreateRolLine",
                Description = "创建圆头线",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep { Name=  "Step0", Options= "RoLINE指定起点:" },
                    new LcCreateStep { Name=  "Step1", Options= "RoLINE下一个点:" },
                    new LcCreateStep { Name=  "Step2", Options= "RoLINE下一个点:" },
                }
            };

        }

        internal static void Initilize()
        {
            ElementActions.RoLine = new RolLineAction();
            LcDocument.ElementActions.Add(BuiltinElementType.RoLine, ElementActions.RoLine);
        }
        private InElementsInputer InElementsInputer { get; set; }
        private ElementSetInputer ElementInputers { get; set; }
        private ElementInputer ElementInputer { get; set; }
        private CmdTextInputer CmdTextInputer { get; set; }
        private PointInputer PointInputer { get; set; }
        private RolLineAction() { }
        public RolLineAction(DocumentRuntime docRt) : base(docRt)
        {
            docRt.CommandCtrl.WriteInfo("命令：ROL");
        }

        public async void ExecCreate(string[] args = null)
        {
             //DocumentManager.CurrentRecorder.BeginAction("PolyLine");
            this.StartCreating();
            this.Segments = new List<RolineSegment>();
            var curMethod = CreateMethods[0];
            this.ElementInputers = new ElementSetInputer(this.docRt);
            this.CmdTextInputer = new CmdTextInputer(this.docRt);
            this.PointInputer = new PointInputer(this.docRt);
            string name = "";
            string description = "";
            Step0:
            polyLineType = PlineSegmentType.Line;
            var step0 = curMethod.Steps[0];
            var result0 = await PointInputer.Execute(step0.Options);
            if (PointInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (result0 == null)
            {
                this.Cancel();
                goto End;
            }
            if (result0.Value == null)
            {
                if (result0.Option != null)
                {
                    goto Step0;
                    //TODO:AutoCAD画线输入一个数字，是怎么确定点的？
                }
                else
                    goto Step1;
            }
            else
            {

                this.startPoint = (Vector2d)result0.Value;
                goto Step1;
            }
            Step1:
            var step1 = curMethod.Steps[1];
            var result1 = await PointInputer.Execute(step1.Options);
            if (PointInputer.isCancelled)
            {
                this.Cancel();
                return;
            }
            if (result1.Value == null)
            {
                if (result1.Option != null) {
                    goto Step1;
                
                }


            }
            else
            {
                this.secondPoint = (Vector2d)result1.Value;
                RolineSegment pl = new RolineSegment();
                pl.Start = (Vector2d)this.startPoint;
                pl.Second = (Vector2d)this.secondPoint;
                Segments.Add(pl);
                goto Step2;
            }

            Step2:
            var step2 = curMethod.Steps[2];
            var result2 = await PointInputer.Execute(step2.Options);
            if (PointInputer.isCancelled)
            {
                if (Segments.Count > 0) {
                    var point= Segments[0].Second;
                    Segments[0].End = point;
                    Segments[0].Second = new Vector2d(); 
                }
                this.Cancel();
                goto End;
            }
            if (result2.Value == null)
            {
                if (result2.Option!=null)
                {
                    goto Step2;
                }
               

            }
            else
            {

                this.endPoint = (Vector2d)result2.Value;
                if (Segments.Count > 0)
                {
                    var point = Segments[0].Second;
                    Segments[0].End = (Vector2d)endPoint;

                }
                CreatePolyLine(Segments);
                goto End ;
            }
            
            End:
            this.EndCreating();
 
        }

        private bool CreatePolyLine(List<RolineSegment> Segments)
        {
            var doc = this.docRt.Document;
             DocumentManager.CurrentRecorder.BeginAction("RoLine");
            var RoLine = doc.CreateObject<LcRoLine>();
            RoLine.Segments = Segments;
            doc.ModelSpace.InsertElement(RoLine);
            this.docRt.Action.ClearSelects();
            DocumentManager.CurrentRecorder.EndAction();
            return true;
        }
        public override void Cancel()
        {
            base.Cancel();
            this.vportRt.SetCreateDrawer(null);
            //TODO:
            this.EndCreating();
        }
        public override void DrawAuxLines(SKCanvas canvas)
        {
            if (secondPoint != null)
            {
                var mp = this.vportRt.PointerMovedPosition.ToVector2d();
                var wcs_mp = this.vportRt.ConvertScrToWcs(mp);
                DrawAuxLine(canvas, secondPoint.Value, wcs_mp);
            }
            else {

                if (startPoint != null)
                {
                    var mp = this.vportRt.PointerMovedPosition.ToVector2d();
                    var wcs_mp = this.vportRt.ConvertScrToWcs(mp);
                    DrawAuxLine(canvas, startPoint.Value, wcs_mp);
                }
            }
            
        }
        private void DrawAuxLine(SKCanvas canvas, Vector2d p0, Vector2d p1)
        {
            var sk_pre = this.vportRt.ConvertWcsToScr(p0).ToSKPoint();
            var sk_p = this.vportRt.ConvertWcsToScr(p1).ToSKPoint();
            //辅助元素的颜色 
            canvas.DrawLine(sk_pre, sk_p, Constants.auxElementPen);
            //辅助曲线的颜色，包括辅助长度，辅助角度等
        }
        public override void Draw(SKCanvas canvas, LcElement element, Vector2d offset)
        {
            Matrix3d matrix = Matrix3d.Translate(offset);
            var grp = element as LcRoLine;
            foreach (var ele in grp.Segments)
            {
                var mstart = matrix.MultiplyPoint(ele.Start);
                var mssecond = matrix.MultiplyPoint(ele.Second);
                var mend = matrix.MultiplyPoint(ele.End);
                var start = this.vportRt.ConvertWcsToScr(mstart).ToSKPoint();
                var second = this.vportRt.ConvertWcsToScr(mssecond).ToSKPoint();
                var end = this.vportRt.ConvertWcsToScr(mend).ToSKPoint();
                var pen = this.GetDrawPen(element);

                if (second != null)
                {
                    if (pen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(start, second, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(start, second, pen);
                    }
                    if (pen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(second, end, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(second, end, pen);
                    }


                }
                else {
                    if (pen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(start, end, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(start, end, pen);
                    }
                }



                
                    var EndAngle = 90;
                    var center =
                        this.vportRt.ConvertWcsToScr(matrix.MultiplyPoint(ele.End)).ToSKPoint();
                    double radius = 10;
                    float x1 = (float)(center.X - radius);
                    float y1 = (float)(center.Y - radius);
                    float x2 = (float)(center.X + radius);
                    float y2 = (float)(center.Y + radius);
                    SKRect skrect = new SKRect(x1, y1, x2, y2);

                   
                    double Degrees;
                    bool dr;

                   
                        if (EndAngle > 180)
                        {
                            Degrees = GetDegreesByTwoLine(new(ele.End.X, ele.End.Y), new(ele.End.X + radius, ele.End.Y), new(ele.End.X, ele.End.Y), new(mstart.X, mstart.Y));

                            dr = IsPlugAng(new(ele.End.X, ele.End.Y), new(ele.End.X + radius, ele.End.Y), new(ele.End.X, ele.End.Y), new(mstart.X, mstart.Y));
                        }
                        else
                        {
                            Degrees = GetDegreesByTwoLine(new(ele.End.X, ele.End.Y), new(ele.End.X + radius, ele.End.Y), new(ele.End.X, ele.End.Y), new(mend.X, mend.Y));
                            dr = IsPlugAng(new(ele.End.X, ele.End.Y), new(ele.End.X + radius, ele.End.Y), new(ele.End.X, ele.End.Y), new(mend.X, mend.Y));
                        }

                  
                   
                    if (pen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {
                            if (dr)
                                canvas.DrawArc(skrect, (float)(360.0 - Degrees), (float)EndAngle, false, elePen);

                            else canvas.DrawArc(skrect, (float)Degrees, (float)EndAngle, false, elePen);

                        }
                    }
                    else
                    {
                        if (dr)
                            canvas.DrawArc(skrect, (float)(360.0 - Degrees), (float)EndAngle, false, pen);

                        else canvas.DrawArc(skrect, (float)Degrees, (float)EndAngle, false, pen);

                    }


            }
           

        }

        public override void CreateElement(LcElement element, Matrix3d matrix)
        {
            var grp = element as LcGroup;
            foreach (var ele in grp.Elements)
            {
                var eleAction = (ele.RtAction as ElementAction);
                eleAction.CreateElement(ele, matrix);
            }
        }
        public override void CreateElement(LcElement element, Vector2d basePoint, double scaleFactor)
        {
            var grp = element as LcGroup;
            foreach (var ele in grp.Elements)
            {
                var eleAction = (ele.RtAction as ElementAction);
                eleAction.CreateElement(ele, basePoint, scaleFactor);
            }

        }
        public override void CreateElement(LcElement element, Vector2d basePoint, Vector2d scaleVector)
        {
            var grp = element as LcGroup;
            foreach (var ele in grp.Elements)
            {
                var eleAction = (ele.RtAction as ElementAction);
                eleAction.CreateElement(ele, basePoint, scaleVector);
            }

        }
        private bool getCircleBy3P(Vector2d a, Vector2d b, Vector2d c, out Vector2d? center, out double radius)
        {
            double A, B, C, D;
            double x1 = a.X, x2 = b.X, x3 = c.X;
            double y1 = a.Y, y2 = b.Y, y3 = c.Y;
            //已知三个点确定圆的半径和圆心 
            double x1x1 = x1 * x1;
            double y1y1 = y1 * y1;
            double x2x2 = x2 * x2;
            double y2y2 = y2 * y2;
            double x3x3 = x3 * x3;
            double y3y3 = y3 * y3;

            double x2y3 = x2 * y3;
            double x3y2 = x3 * y2;

            double x2_x3 = x2 - x3;
            double y2_y3 = y2 - y3;

            double x1x1py1y1 = x1x1 + y1y1;
            double x2x2py2y2 = x2x2 + y2y2;
            double x3x3py3y3 = x3x3 + y3y3;

            A = x1 * y2_y3 - y1 * x2_x3 + x2y3 - x3y2;
            if (A == 0)
            {
                center = null;
                radius = 0;
                return false;
            }
            B = x1x1py1y1 * (-y2_y3) + x2x2py2y2 * (y1 - y3) + x3x3py3y3 * (y2 - y1);
            C = x1x1py1y1 * x2_x3 + x2x2py2y2 * (x3 - x1) + x3x3py3y3 * (x1 - x2);
            D = x1x1py1y1 * (x3y2 - x2y3) + x2x2py2y2 * (x1 * y3 - x3 * y1) + x3x3py3y3 * (x2 * y1 - x1 * y2);

            var x = -B / (2 * A);
            var y = -C / (2 * A);
            radius = Math.Sqrt((B * B + C * C - 4 * A * D) / (4 * A * A));
            center = new Vector2d(x, y);
            return true;
        }
        public Tuple<Vector2d, Vector2d, double> GetCircleBy2PD(Vector2d start, Vector2d End, double degrees)
        {
            double point1X = start.X;
            double point1Y = start.Y;
            double point2X = End.X;
            double point2Y = End.Y;
            double angleDegrees = degrees;

            // 计算中点坐标
            double midPointX = (point1X + point2X) / 2;
            double midPointY = (point1Y + point2Y) / 2;

            // 计算两个点之间的距离
            double distance = Math.Sqrt(Math.Pow(point2X - point1X, 2) + Math.Pow(point2Y - point1Y, 2));

            // 将角度转换为弧度
            double radians = angleDegrees * Math.PI / 180;

            double radius = distance / (2 * Math.Sin(radians / 2));
            //// 计算圆心的偏移量
            //double offsetX = distance * Math.Cos(radians);
            //double offsetY = distance * Math.Sin(radians);
            double centerX = midPointX + radius * Math.Cos(radians / 2);
            double centerY = midPointY + radius * Math.Sin(radians / 2);
            // 计算圆心的坐标
            //double centerX = midPointX + offsetX;
            //double centerY = midPointY + offsetY;
            //double radius = Math.Sqrt(Math.Pow(centerX - point1X, 2) + Math.Pow(centerY - point1Y, 2));


            double dx = point2X - point1X;
            double dy = point2Y - point1Y;

            ///# 将向量差单位化
            double unit_dx = dx / distance;
            double unit_dy = dy / distance;

            ///# 计算圆心坐标
            double h = midPointX + radius * unit_dx;
            double k = midPointY + radius * unit_dy;

            var b = start;
            var a = End;
            var r = radius;

            double c1 = (b.X * b.X - a.X * a.X + b.Y * b.Y - a.Y * a.Y) / (2 * (b.X - a.X));
            double c2 = (b.Y - a.Y) / (b.X - a.X);
            double A = (c2 * c2 + 1);
            double B = (2 * a.X * c2 - 2 * c1 * c2 - 2 * a.Y);
            double C = a.X * a.X - 2 * a.X * c1 + c1 * c1 + a.Y * a.Y - r * r;
            Vector2d center1;
            Vector2d center2;

            center1.Y = (-B - Math.Sqrt(B * B - 4 * A * C)) / (2 * A);

            center2.Y = (-B + Math.Sqrt(B * B - 4 * A * C)) / (2 * A);

            center1.X = c1 - c2 * center1.Y;
            center2.X = c1 - c2 * center2.Y;
            return new Tuple<Vector2d, Vector2d, double>(center1, center2, radius);
        }
        /// <summary>
        /// 切线加终止点画弧线  返回圆心和角度
        /// </summary>
        /// <param name="lineStart"></param>
        /// <param name="lineEnd"></param>
        /// <param name="point"></param>
        /// <returns>  圆心，半径，弧度</returns>
        public Tuple<Vector2d, double, double> GetCircleBylinePoint(Vector2d lineStart, Vector2d lineEnd, Vector2d point)
        {
            //  return null;
            bool plugang = IsPlugAng(lineEnd, lineStart, lineEnd, point);
            bool pointIsTop = true;

            int tp = IsTopInLine(lineStart, lineEnd, point);
            if (tp == 0)
            {
                return null;//在同一条线上画直线
            }

            double Degrees = GetDegreesByTwoLine(lineStart, lineEnd, lineEnd, point);

            Degrees = 180 - (90 - Degrees) * 2;

            Tuple<Vector2d, Vector2d, double> cirTuple = GetCircleBy2PD(lineEnd, point, Degrees);
            int tc = IsTopInLine(lineEnd, point, cirTuple.Item1);
            Vector2d circenter;
            if (Degrees<180 )//圆心和线要在同一边 当弧度小于半圆，大于半圆时 ，向量反之  
            {
                if(tc == tp)
                circenter = cirTuple.Item1;
                else circenter = cirTuple.Item2;
            }
            else
            {
                if (tc != tp)
                    circenter = cirTuple.Item1;
                else circenter = cirTuple.Item2;
            }
            /// 圆心，半径，弧度
            return new Tuple<Vector2d, double, double>(circenter, cirTuple.Item3, Degrees);
        }


        /// <summary>
        /// 获取两条线的夹角  
        /// </summary>
        /// <param name="line1start"></param>
        /// <param name="line1End"></param>
        /// <param name="line2start"></param>
        /// <param name="line2End"></param>
        /// <returns></returns>
        public double GetDegreesByTwoLine(Vector2d line1start, Vector2d line1End, Vector2d line2start, Vector2d line2End)
        {
            double x1 = line1start.X;
            double y1 = line1start.Y;
            double x2 = line1End.X;
            double y2 = line1End.Y;
            double x3 = line2start.X;
            double y3 = line2start.Y;
            double x4 = line2End.X;
            double y4 = line2End.Y;

            // 计算线段的向量表示
            double v1x = x2 - x1;
            double v1y = y2 - y1;
            double v2x = x4 - x3;
            double v2y = y4 - y3;

            // 计算向量的内积
            double dotProduct = v1x * v2x + v1y * v2y;

            // 计算向量的长度
            double magnitudeV1 = Math.Sqrt(v1x * v1x + v1y * v1y);
            double magnitudeV2 = Math.Sqrt(v2x * v2x + v2y * v2y);

            // 计算夹角余弦值
            double cosine = dotProduct / (magnitudeV1 * magnitudeV2);

            // 将夹角余弦值转换为角度
            double angleRadians = Math.Acos(cosine);
            double angleDegrees = angleRadians * 180 / Math.PI;
            return angleDegrees;
        }
        public bool IsPlugAng(Vector2d line1start, Vector2d line1End, Vector2d line2start, Vector2d line2End)
        {
            double x1 = line1start.X;
            double y1 = line1start.Y;
            double x2 = line1End.X;
            double y2 = line1End.Y;
            double x3 = line2start.X;
            double y3 = line2start.Y;
            double x4 = line2End.X;
            double y4 = line2End.Y;
            if (x1 == x2)
            {
                if (x4 < x1)
                {
                    return true;

                }
                else
                {
                    return false;

                }
            }
            else
                if (y1 == y2)
            {
                if (y4 > y1)
                {
                    return true;

                }
                else
                {
                    return false;
                }
            }
            else
            {
                //             a = ( x1, y1) b = (x2, y2)
                //a×b = x1y2 - x2y1
                //若结果为正，则向量b在a的逆时针方向
                //否则，b在a的顺时针方向


                double xa = x2 - x1;
                double ya = y2 - y1;
                double xb = x4 - x3;
                double yb = y4 - y3;
                double angle = xa * yb - xb * ya;
                if (angle > 0)
                { return true; }
                else
                { return false; }
                //# 计算斜率
                //double m1 = (y2 - y1) / (x2 - x1);
                //double m2 = (y4 - y3) / (x4 - x3);
                //double angle = Math.Abs(Math.Tan(m2) - Math.Tan(m1));


                ////if (x2 > x1 && y2 > y1)
                ////{
                ////    if (m2 < m1)
                ////        return false;
                ////}
                ////else if (x2 < x1 && y2 > y1)
                ////{
                ////    if (m2 > m1)
                ////        return false;
                ////}
                ////else if (x2 < x1 && y2 < y1)
                ////{
                ////    if (m2 < m1)
                ////        return false;
                ////}
                ////else if (x2 > x1 && y2 < y1)
                ////{
                ////    if (m2 > m1)
                ////        return false;
                ////}
                //double angle1 = Math.Tan((m2 - m1) / (1 + m1 * m2));
                //if (angle1 > 0)
                //{ return false; }
                //else
                //{ return true; }



            }
        }
        public int IsTopInLine(Vector2d line1start, Vector2d line1End, Vector2d point)
        {
            Vector2d S;
            Vector2d E;
            //if (line1start.X < line1End.X)
            //{
            //    S = line1start;
            //    E = line1End;

            //}
            //else
            //   if (line1start.X == line1End.X)
            //{
            //    if (line1start.Y < line1End.Y)
            //    {
            //        S = line1start;
            //        E = line1End;

            //    }
            //    else
            //    {
            //        S = line1End;
            //        E = line1start;


            //    }
            //}
            //else
            //{
                S = line1End;
                E = line1start;

           // }
            double Tmp = (S.Y - E.Y) * point.X + (E.X - S.X) * point.Y + S.X * E.Y - E.X * S.Y;
            if (Tmp == 0)
            {
                return 0;
            }
            if (Tmp > 0)
            {
                return 1;
            }
            else
            { return -1; }
            //                Tmp > 0 在左侧

            //Tmp = 0 在线上

            //Tmp < 0 在右侧
        }
        public Vector2d GetVerticalpoint(Vector2d point, Vector2d center, Vector2d spoint, double ANG)
        {
            double x1 = point.X;
            double y1 = point.Y;
            double x2 = center.X;
            double y2 = center.Y;
            double x;
            double y;
            if (x1 == x2)
            {
                y = spoint.Y;
                x = x1;
            }
            else
            if (y1 == y2)
            {
                y = y1;
                x = spoint.X;
                //return (new(x1, y1 + 1));
            }
            else
            {
                double k1 = (y2 - y1) / (x2 - x1);


                double b1 = y1 - k1 * x1;
                double k = -1 / k1;
                double b = spoint.Y - k * spoint.X;
                x = (b1 - b) / (k - k1);
                y = k * x + b;

            }

            if (ANG < 180)
            {
                Matrix3d matrix31 = Matrix3d.Move(new Vector2d(x, y), point);
                return matrix31.MultiplyPoint(spoint);

            }
            else

            {
                Matrix3d matrix31 = Matrix3d.Move(spoint, point);
                return matrix31.MultiplyPoint(new Vector2d(x, y));
            }





        }
        public override void DrawTemp(SKCanvas canvas)
        {
            if (this.startPoint == null)
            {
                return;
            }

            var mp = this.vportRt.PointerMovedPosition.ToVector2d();
            var wcs_mp = this.vportRt.ConvertScrToWcs(mp);
            var sk_p = this.vportRt.ConvertWcsToScr(wcs_mp).ToSKPoint();

            foreach (var ele in this.Segments)
            {
                //var mstart = matrix.MultiplyPoint(ele.Start);
                //var mend = matrix.MultiplyPoint(ele.End);
                var start = this.vportRt.ConvertWcsToScr(ele.Start).ToSKPoint();
                var second = this.vportRt.ConvertWcsToScr(ele.Second).ToSKPoint();
                var end = this.vportRt.ConvertWcsToScr(ele.End).ToSKPoint();
                if (second != null)
                {
                    
                        using (var elePen = new SKPaint { Color = SKColors.Green, IsStroke = true })
                        {

                            canvas.DrawLine(start, second, elePen);
                       
                         }

                    if (ele.End.X == 0 && ele.End.Y == 0) { } else {
                        using (var elePen =  new SKPaint { Color = SKColors.Green, IsStroke = true })
                        {

                            canvas.DrawLine(second, end, elePen);
                        }
                    }
                   



                }
                else
                {
                   
                        using (var elePen = new SKPaint { Color = SKColors.Green, IsStroke = true })
                        {

                            canvas.DrawLine(start, end, elePen);
                        }
                   
                }
                //using (var elePen = new SKPaint { Color = SKColors.Green, IsStroke = true })
                //    {
                //        canvas.DrawLine(start, end, elePen);
                //    }
                
            }
            
 
           

        }
        public override void Draw(SKCanvas canvas, LcElement element, Matrix3d matrix)
        {
            var grp = element as LcRoLine;
            foreach (var ele in grp.Segments)
            {
                var mstart = matrix.MultiplyPoint(ele.Start);
                var msecond = matrix.MultiplyPoint(ele.Second);
                var mend = matrix.MultiplyPoint(ele.End);
                var start = this.vportRt.ConvertWcsToScr(mstart).ToSKPoint();
                var second = this.vportRt.ConvertWcsToScr(msecond).ToSKPoint();
                var end = this.vportRt.ConvertWcsToScr(mend).ToSKPoint();
                var pen = this.GetDrawPen(element);

                if (second != null)
                {
                    if (pen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(start, second, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(start, second, pen);
                    }
                    if (pen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(second, end, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(second, end, pen);
                    }


                }
                else
                {
                    if (pen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(start, end, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(start, end, pen);
                    }
                }


            }
          
        }
        
        public override ControlGrip[] GetControlGrips(LcElement element)
        {
            var group = element as LcGroup;
            var grips = new List<ControlGrip>();
            var gripCenter = new ControlGrip
            {
                Element = group,
                Name = "Center",
                Position = group.BoundingBox.Center
            };
            grips.Add(gripCenter);
            return grips.ToArray();
        }
        private string _gripName;
        private Vector2d _position;
        private Vector2d _endDrag;
        private LcGroup _group;

        public override void SetDragGrip(LcElement element, string gripName, Vector2d position, bool isEnd)
        {
            _group = element as LcGroup;

            if (!isEnd)
            {
                _gripName = gripName;
                _position = position;
            }
            else
            {
                if (gripName == "Center")
                {
                    var delta = position - _group.BoundingBox.Center;
                    _group.Translate(delta);
                }
            }
        }


        public override void DrawDragGrip(SKCanvas canvas)
        {
            if (_group == null) return;

            var offset = _position - _group.BoundingBox.Center;
            foreach (var ele in _group.Elements)
            {
                (ele.RtAction as ElementAction).Draw(canvas, ele, offset);
            }
        }

    }
}
